package org.workhorse.persistence.jpa;

import org.workhorse.persistence.BasePersistenceManager;
import org.workhorse.Identifiable;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import java.util.Map;

import com.google.inject.Inject;

/**
 * A {@link org.workhorse.persistence.PersistenceManager WorkManager} for
 * JPA Persistence.
 */
public class JpaPersistenceManager extends BasePersistenceManager
{
    private EntityManager em;

    /**
     * Default constructor passes in the {@code EntityManagerFactory} that will
     * be used to create the {@code EntityManager}.
     * @param emf The factory for the {@code EntityManager}
     */
    @Inject
    public JpaPersistenceManager(EntityManagerFactory emf) {
        em = emf.createEntityManager();
    }

    /**
     * Constructor which takes additional properties for the creation of the
     * {@code EntityManager}.
     * @param emf The factory for the {@code EntityManager}
     * @param properties Additional properties
     */
    public JpaPersistenceManager(EntityManagerFactory emf, Map properties) {
        em = emf.createEntityManager(properties);
    }

    /**
     * Begins a new transaction.
     */
    public void begin() {
        em.getTransaction().begin();
    }

    /**
     * Saves any work in the current transaction.
     */
    public void save() {
        em.getTransaction().commit();
    }

    /**
     * Undo any work in current transaction.
     */
    public void undo() {
        em.getTransaction().rollback();
    }

    /**
     * Persists the object, or merges it into the
     * current persistence context.
     * @param object The object to persist
     */
    public void persist(Identifiable object) {
        em.persist(object);
    }

    /**
     * Makes the object non-persistent.
     * @param object The object to make non-persistent
     */
    public void remove(Object object) {
        em.remove(object);
    }

    /**
     * Closes the {@code JpaPersistenceManager}.
     */
    public void close() {
       em.close();
    }
}
